#include "jsontable/table_helper.h"
#include "struct_attribute.h"

template<> void LoadFromStream(ATTRARITHTYPE &entity, std::istream &stream)
{
	StreamHelper::EnumFromStream(entity, stream);
}

template<> void SaveToStream(const ATTRARITHTYPE &entity, std::ostream &stream)
{
	StreamHelper::EnumToStream(entity, stream);
}

template<> void LoadFromText(ATTRARITHTYPE &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const ATTRARITHTYPE &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(ATTRARITHTYPE &entity, const rapidjson::Value &value)
{
	EnumFromJson(entity, value);
}

template<> void JsonHelper::BlockToJson(const ATTRARITHTYPE &entity, rapidjson::Value &value)
{
	EnumToJson(entity, value);
}

template<> void LoadFromStream(ATTRTYPE &entity, std::istream &stream)
{
	StreamHelper::EnumFromStream(entity, stream);
}

template<> void SaveToStream(const ATTRTYPE &entity, std::ostream &stream)
{
	StreamHelper::EnumToStream(entity, stream);
}

template<> void LoadFromText(ATTRTYPE &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const ATTRTYPE &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(ATTRTYPE &entity, const rapidjson::Value &value)
{
	EnumFromJson(entity, value);
}

template<> void JsonHelper::BlockToJson(const ATTRTYPE &entity, rapidjson::Value &value)
{
	EnumToJson(entity, value);
}

template<> const char *GetTableName<PlayerBase>()
{
	return "player_base";
}

template<> const char *GetTableKeyName<PlayerBase>()
{
	return "level";
}

template<> uint64 GetTableKeyValue(const PlayerBase &entity)
{
	return (uint64)entity.level;
}

template<> void SetTableKeyValue(PlayerBase &entity, uint64 key)
{
	entity.level = (uint32)key;
}

template<> const char *GetTableFieldNameByIndex<PlayerBase>(size_t index)
{
	switch (index)
	{
		case 0: return "level";
		case 1: return "lvUpExp";
		case 2: return "recoveryHPRate";
		case 3: return "recoveryHPValue";
		case 4: return "recoveryMPRate";
		case 5: return "recoveryMPValue";
	}
	return "";
}

template<> ssize_t GetTableFieldIndexByName<PlayerBase>(const char *name)
{
	if (strcmp(name, "level") == 0) return 0;
	if (strcmp(name, "lvUpExp") == 0) return 1;
	if (strcmp(name, "recoveryHPRate") == 0) return 2;
	if (strcmp(name, "recoveryHPValue") == 0) return 3;
	if (strcmp(name, "recoveryMPRate") == 0) return 4;
	if (strcmp(name, "recoveryMPValue") == 0) return 5;
	return -1;
}

template<> size_t GetTableFieldNumber<PlayerBase>()
{
	return 6;
}

template<> std::string GetTableFieldValue(const PlayerBase &entity, size_t index)
{
	switch (index)
	{
		case 0: return StringHelper::ToString(entity.level);
		case 1: return StringHelper::ToString(entity.lvUpExp);
		case 2: return StringHelper::ToString(entity.recoveryHPRate);
		case 3: return StringHelper::ToString(entity.recoveryHPValue);
		case 4: return StringHelper::ToString(entity.recoveryMPRate);
		case 5: return StringHelper::ToString(entity.recoveryMPValue);
	}
	return "";
}

template<> void SetTableFieldValue(PlayerBase &entity, size_t index, const std::string_view &value)
{
	switch (index)
	{
		case 0: return StringHelper::FromString(entity.level, value);
		case 1: return StringHelper::FromString(entity.lvUpExp, value);
		case 2: return StringHelper::FromString(entity.recoveryHPRate, value);
		case 3: return StringHelper::FromString(entity.recoveryHPValue, value);
		case 4: return StringHelper::FromString(entity.recoveryMPRate, value);
		case 5: return StringHelper::FromString(entity.recoveryMPValue, value);
	}
}

template<> void LoadFromStream(PlayerBase &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.level, stream);
	StreamHelper::FromStream(entity.lvUpExp, stream);
	StreamHelper::FromStream(entity.recoveryHPRate, stream);
	StreamHelper::FromStream(entity.recoveryHPValue, stream);
	StreamHelper::FromStream(entity.recoveryMPRate, stream);
	StreamHelper::FromStream(entity.recoveryMPValue, stream);
}

template<> void SaveToStream(const PlayerBase &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.level, stream);
	StreamHelper::ToStream(entity.lvUpExp, stream);
	StreamHelper::ToStream(entity.recoveryHPRate, stream);
	StreamHelper::ToStream(entity.recoveryHPValue, stream);
	StreamHelper::ToStream(entity.recoveryMPRate, stream);
	StreamHelper::ToStream(entity.recoveryMPValue, stream);
}

template<> void LoadFromText(PlayerBase &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const PlayerBase &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(PlayerBase &entity, const rapidjson::Value &value)
{
	FromJson(entity.level, value, "level");
	FromJson(entity.lvUpExp, value, "lvUpExp");
	FromJson(entity.recoveryHPRate, value, "recoveryHPRate");
	FromJson(entity.recoveryHPValue, value, "recoveryHPValue");
	FromJson(entity.recoveryMPRate, value, "recoveryMPRate");
	FromJson(entity.recoveryMPValue, value, "recoveryMPValue");
}

template<> void JsonHelper::BlockToJson(const PlayerBase &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.level, value, "level");
	ToJson(entity.lvUpExp, value, "lvUpExp");
	ToJson(entity.recoveryHPRate, value, "recoveryHPRate");
	ToJson(entity.recoveryHPValue, value, "recoveryHPValue");
	ToJson(entity.recoveryMPRate, value, "recoveryMPRate");
	ToJson(entity.recoveryMPValue, value, "recoveryMPValue");
}

template<> const char *GetTableName<PlayerAttribute>()
{
	return "player_attribute";
}

template<> const char *GetTableKeyName<PlayerAttribute>()
{
	return "Id";
}

template<> uint64 GetTableKeyValue(const PlayerAttribute &entity)
{
	return (uint64)entity.Id;
}

template<> void SetTableKeyValue(PlayerAttribute &entity, uint64 key)
{
	entity.Id = (uint32)key;
}

template<> const char *GetTableFieldNameByIndex<PlayerAttribute>(size_t index)
{
	switch (index)
	{
		case 0: return "Id";
		case 1: return "career";
		case 2: return "level";
		case 3: return "attrs";
		case 4: return "damageFactor";
	}
	return "";
}

template<> ssize_t GetTableFieldIndexByName<PlayerAttribute>(const char *name)
{
	if (strcmp(name, "Id") == 0) return 0;
	if (strcmp(name, "career") == 0) return 1;
	if (strcmp(name, "level") == 0) return 2;
	if (strcmp(name, "attrs") == 0) return 3;
	if (strcmp(name, "damageFactor") == 0) return 4;
	return -1;
}

template<> size_t GetTableFieldNumber<PlayerAttribute>()
{
	return 5;
}

template<> std::string GetTableFieldValue(const PlayerAttribute &entity, size_t index)
{
	switch (index)
	{
		case 0: return StringHelper::ToString(entity.Id);
		case 1: return StringHelper::ToString(entity.career);
		case 2: return StringHelper::ToString(entity.level);
		case 3: return JsonHelper::SequenceToJsonText(entity.attrs);
		case 4: return StringHelper::ToString(entity.damageFactor);
	}
	return "";
}

template<> void SetTableFieldValue(PlayerAttribute &entity, size_t index, const std::string_view &value)
{
	switch (index)
	{
		case 0: return StringHelper::FromString(entity.Id, value);
		case 1: return StringHelper::FromString(entity.career, value);
		case 2: return StringHelper::FromString(entity.level, value);
		case 3: return JsonHelper::SequenceFromJsonText(entity.attrs, value);
		case 4: return StringHelper::FromString(entity.damageFactor, value);
	}
}

template<> void LoadFromStream(PlayerAttribute &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.Id, stream);
	StreamHelper::FromStream(entity.career, stream);
	StreamHelper::FromStream(entity.level, stream);
	StreamHelper::SequenceFromStream(entity.attrs, stream);
	StreamHelper::FromStream(entity.damageFactor, stream);
}

template<> void SaveToStream(const PlayerAttribute &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.Id, stream);
	StreamHelper::ToStream(entity.career, stream);
	StreamHelper::ToStream(entity.level, stream);
	StreamHelper::SequenceToStream(entity.attrs, stream);
	StreamHelper::ToStream(entity.damageFactor, stream);
}

template<> void LoadFromText(PlayerAttribute &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const PlayerAttribute &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(PlayerAttribute &entity, const rapidjson::Value &value)
{
	FromJson(entity.Id, value, "Id");
	FromJson(entity.career, value, "career");
	FromJson(entity.level, value, "level");
	SequenceFromJson(entity.attrs, value, "attrs");
	FromJson(entity.damageFactor, value, "damageFactor");
}

template<> void JsonHelper::BlockToJson(const PlayerAttribute &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.Id, value, "Id");
	ToJson(entity.career, value, "career");
	ToJson(entity.level, value, "level");
	SequenceToJson(entity.attrs, value, "attrs");
	ToJson(entity.damageFactor, value, "damageFactor");
}

template<> const char *GetTableName<CreatureAttribute>()
{
	return "creature_attribute";
}

template<> const char *GetTableKeyName<CreatureAttribute>()
{
	return "Id";
}

template<> uint64 GetTableKeyValue(const CreatureAttribute &entity)
{
	return (uint64)entity.Id;
}

template<> void SetTableKeyValue(CreatureAttribute &entity, uint64 key)
{
	entity.Id = (uint64)key;
}

template<> const char *GetTableFieldNameByIndex<CreatureAttribute>(size_t index)
{
	switch (index)
	{
		case 0: return "Id";
		case 1: return "type";
		case 2: return "level";
		case 3: return "round";
		case 4: return "attrs";
		case 5: return "damageFactor";
	}
	return "";
}

template<> ssize_t GetTableFieldIndexByName<CreatureAttribute>(const char *name)
{
	if (strcmp(name, "Id") == 0) return 0;
	if (strcmp(name, "type") == 0) return 1;
	if (strcmp(name, "level") == 0) return 2;
	if (strcmp(name, "round") == 0) return 3;
	if (strcmp(name, "attrs") == 0) return 4;
	if (strcmp(name, "damageFactor") == 0) return 5;
	return -1;
}

template<> size_t GetTableFieldNumber<CreatureAttribute>()
{
	return 6;
}

template<> std::string GetTableFieldValue(const CreatureAttribute &entity, size_t index)
{
	switch (index)
	{
		case 0: return StringHelper::ToString(entity.Id);
		case 1: return StringHelper::ToString(entity.type);
		case 2: return StringHelper::ToString(entity.level);
		case 3: return StringHelper::ToString(entity.round);
		case 4: return JsonHelper::SequenceToJsonText(entity.attrs);
		case 5: return StringHelper::ToString(entity.damageFactor);
	}
	return "";
}

template<> void SetTableFieldValue(CreatureAttribute &entity, size_t index, const std::string_view &value)
{
	switch (index)
	{
		case 0: return StringHelper::FromString(entity.Id, value);
		case 1: return StringHelper::FromString(entity.type, value);
		case 2: return StringHelper::FromString(entity.level, value);
		case 3: return StringHelper::FromString(entity.round, value);
		case 4: return JsonHelper::SequenceFromJsonText(entity.attrs, value);
		case 5: return StringHelper::FromString(entity.damageFactor, value);
	}
}

template<> void LoadFromStream(CreatureAttribute &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.Id, stream);
	StreamHelper::FromStream(entity.type, stream);
	StreamHelper::FromStream(entity.level, stream);
	StreamHelper::FromStream(entity.round, stream);
	StreamHelper::SequenceFromStream(entity.attrs, stream);
	StreamHelper::FromStream(entity.damageFactor, stream);
}

template<> void SaveToStream(const CreatureAttribute &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.Id, stream);
	StreamHelper::ToStream(entity.type, stream);
	StreamHelper::ToStream(entity.level, stream);
	StreamHelper::ToStream(entity.round, stream);
	StreamHelper::SequenceToStream(entity.attrs, stream);
	StreamHelper::ToStream(entity.damageFactor, stream);
}

template<> void LoadFromText(CreatureAttribute &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const CreatureAttribute &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(CreatureAttribute &entity, const rapidjson::Value &value)
{
	FromJson(entity.Id, value, "Id");
	FromJson(entity.type, value, "type");
	FromJson(entity.level, value, "level");
	FromJson(entity.round, value, "round");
	SequenceFromJson(entity.attrs, value, "attrs");
	FromJson(entity.damageFactor, value, "damageFactor");
}

template<> void JsonHelper::BlockToJson(const CreatureAttribute &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.Id, value, "Id");
	ToJson(entity.type, value, "type");
	ToJson(entity.level, value, "level");
	ToJson(entity.round, value, "round");
	SequenceToJson(entity.attrs, value, "attrs");
	ToJson(entity.damageFactor, value, "damageFactor");
}
